package sfsu.memopad;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import android.app.ListActivity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class AddGroupMembers extends ListActivity{
	// Activity Id Numbers.
		private static final int ALLUSERS = 0;
		private static final int GROUPUSERS = 1;
		private static final int SAVE = 3;

		private int activity;
		private String server = "http://10.0.2.2:9226/";
		private int groupID = 100;

		private ArrayList<String> groupMembers = new ArrayList<String>();
		private ArrayList<String> allUsers = new ArrayList<String>();
		private ArrayList<String> checkOn = new ArrayList<String>();

		private String passData;
		private String userName = "DF";

		/** Called when the activity is first created. */
		@Override
		public void onCreate(Bundle savedInstanceState) {
			super.onCreate(savedInstanceState);
			setTitle(R.string.addGroupMembers);
			
			Bundle extras = getIntent().getExtras();
			if (extras != null) {
				groupID = extras.getInt("GROUPID");
				userName = extras.getString("USERNAME");
			}
			
			requestAllUsers();
		}
		
		@Override
		public void onBackPressed() {
			saveGroupMembers();
			Intent intent = new Intent();
			setResult(RESULT_OK, intent);
			finish();
		}

		/*
		 * Calls setGroupList on the location user touched on the screen.
		 */
		protected void onListItemClick(ListView l, View v, int position, long id) {
			super.onListItemClick(l, v, position, id);
			setGroupList(position);
		}

		/*
		 * Add and removes from the group's member list. 
		 */
		private void setGroupList(int index) {
			if (checkOn.contains(allUsers.get(index))) {
				checkOn.remove(checkOn.indexOf(allUsers.get(index)));
				Log.d("ListView", "setGroupList: remove " + allUsers.get(index));
			} else {
				checkOn.add(allUsers.get(index));
				Log.d("ListView", "setGroupList: added " + allUsers.get(index));
			}
		}
		
		/*
		 * Set check marks for users that are already group members.
		 */
		private void checkGroupUsers() {
			for(int x = 0; x < allUsers.size(); x++) {
				if(groupMembers.contains(allUsers.get(x))) {
					getListView().setItemChecked(x, true);
					checkOn.add(allUsers.get(x));
				}
			}
		}
		
		/*
		 * Network requests to the server.
		 */
		private void requestGroupMembers() {
			activity = GROUPUSERS;
			new NetworkCall().execute(server + "GROUPUSERS<CMD>" + groupID	+ "<CMD>");
		}
		
		private void requestAllUsers() {
			activity = ALLUSERS;
			new NetworkCall().execute(server + "ALLUSERS<CMD>");
		}
		
		/*
		 * Sends to the server all edits of the group's member list.
		 */
		private void saveGroupMembers() {
			//String sendList = userName + "<CR>"; // Use if it is set to not show userName on list.
			String sendList = "";
			for(int x = 0; x < checkOn.size(); x++) {
				sendList += checkOn.get(x) + "<CR>";
			}
			
			activity = SAVE;
			new NetworkCall().execute(server + "SAVEGROUPUSERS<CMD>" + groupID + "<CMD>" + sendList);
		}

		/*
		 * Processes what happens after returning from a network call.
		 */
		public void onNetworkResult() {
			switch (activity) {
			case ALLUSERS:
				String[] members = passData.split("\n");
				for (int x = 0; x < members.length; x++) {
					//if (!members[x].contentEquals(userName)) { // Use if you do not want to show userName on list.
						allUsers.add(members[x]);
					//}
				}

				ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, allUsers);
				getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
				//getListView().setBackgroundColor(0x00808080);
				setListAdapter(adapter);

				requestGroupMembers();
				break;
			case GROUPUSERS:
				String[] groupM = passData.split("\n");
				for (int x = 0; x < groupM.length; x++) {
					//if (!groupM[x].contentEquals(userName)) { // Use if you do not want to show userName on list.
						groupMembers.add(groupM[x]);
					//}
				}
				
				checkGroupUsers();
				break;
			}
		}
		
		public class NetworkCall extends AsyncTask<String, Void, String> {
			@Override
			protected void onPreExecute() {
				Log.i("AsyncTask", "onPreExecute");
			}

			/*
			 * Opens a Http connection to a server.
			 */
			private InputStream OpenHttpConnection(String urlString) throws IOException {
				InputStream in = null;
				int response = -1;

				try {
					URL url = new URL(urlString);
					URLConnection conn = url.openConnection();

					if (!(conn instanceof HttpURLConnection))
						throw new IOException("Not an HTTP connection");
					try {
						HttpURLConnection httpConn = (HttpURLConnection) conn;
						httpConn.setAllowUserInteraction(false);
						httpConn.setInstanceFollowRedirects(true);
						httpConn.setRequestMethod("GET");
						httpConn.connect();
						response = httpConn.getResponseCode();
						if (response == HttpURLConnection.HTTP_OK) {
							in = httpConn.getInputStream();
						}
					} catch (Exception ex) {
						Log.d("Networking", ex.getLocalizedMessage());
						throw new IOException("Error connecting");
					}
				} catch (MalformedURLException e) {
					Log.d("Networking", "Error opening URL: " + e);
				}
				return in;
			}

			/*
			 * Pulls string from server.
			 */
			private String DownloadText(String URL) {
				int BUFFER_SIZE = 2000;
				InputStream in = null;
				try {
					in = OpenHttpConnection(URL);
				} catch (IOException e) {
					Log.d("NetworkingActivity", e.getLocalizedMessage());
					return "";
				}

				InputStreamReader isr = new InputStreamReader(in);
				int charRead;
				String str = "";
				char[] inputBuffer = new char[BUFFER_SIZE];
				try {
					while ((charRead = isr.read(inputBuffer)) > 0) {
						// ---convert the chars to a String---
						String readString = String
								.copyValueOf(inputBuffer, 0, charRead);
						str += readString;
						inputBuffer = new char[BUFFER_SIZE];
					}
					in.close();
				} catch (IOException e) {
					Log.d("NetworkingActivity", e.getLocalizedMessage());
					return "";
				}
				return str;
			}

			// Set up DownloadText as occurs in the background.
			@Override
			protected String doInBackground(String... urls) {
				Log.i("NetworkCall", "doInBackgroup: " + urls);
				return DownloadText(urls[0]);
			}

			/*
			 * On completion of Async task, the string pulled from the server is saved
			 * in passData.
			 */
			@Override
			protected void onPostExecute(String result) {
				passData = result;
				//Log.d("Network", result);
				onNetworkResult();
			}
		}
	}
